package com.sn.springboot_netty.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.time.Duration;

/**
 * redis配置类，修改序列化方式
 * 默认为JDK
 * 修改为：GenericJackson2JsonRedisSerializer，Jackson2JsonRedisSerializer
 * 序列化反序列化带泛型的List数据:
 * Jackson2JsonRedisSerializer:
 *  序列化带泛型的数据时，会以map的结构进行存储，反序列化是不能将map解析成对象
 *  解决方案：序列化存储时，转成JSON字符串 JSON.toJSONString(userToken)
 * GenericJackson2JsonRedisSerializer:
 *  序列化时，会保存序列化的对象的包名和类名，反序列化时以这个作为标示就可以反序列化成指定的对象
 *  也可以以JSON字符串保存 JSON.toJSONString(userToken)
 *
 *  可以正常序列化反序列化非泛型数组对象
 *
 *  效率：GenericJackson2JsonRedisSerializer < Jackson2JsonRedisSerializer
 */
@Configuration
public class RedisConfig {

    @Bean(name = "jackson2JsonRedisSerializer")
    public Jackson2JsonRedisSerializer jackson2JsonRedisSerializer(){
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
        jackson2JsonRedisSerializer.setObjectMapper(om);
        return jackson2JsonRedisSerializer;
    }

    @Bean(name = "genericJackson2JsonRedisSerializer")
    public GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer(){
        return new GenericJackson2JsonRedisSerializer();
    }

    @Bean(name = "myRedisTemplate")
    public RedisTemplate<Object,Object> myRedisTemplate(
            RedisConnectionFactory redisConnectionFactory, GenericJackson2JsonRedisSerializer ser)
            throws UnknownHostException {
        RedisTemplate<Object,Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setDefaultSerializer(ser); //设置序列化方式
        return template;
    }

    @Bean(value = "redisCacheManager")
    public CacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory){
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

        // 配置序列化（解决乱码的问题）
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(30))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer))
                .disableCachingNullValues();

        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }


}
